bitkeeper revision 1.815 (405ed20aUPuCpxY9bW6IV5l8ztG3Og)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Mon, 22 Mar 2004 11:46:18 +0000 (11:46 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Mon, 22 Mar 2004 11:46:18 +0000 (11:46 +0000)
console.c, console_client.py, Xeno-HOWTO.txt, README.CD:
  Many console fixes.

README.CD
docs/Xeno-HOWTO.txt
tools/xenctl/lib/console_client.py
xenolinux-2.4.25-sparse/arch/xeno/drivers/console/console.c

index 0683c4cfe9ac532148cc13b9aa3d8a2493c7a9c1..0301030c64c29184f38b3436ac351f9bc84bd555 100644 (file)
--- a/README.CD
+++ b/README.CD
@@ -536,19 +536,24 @@ given direct access to the graphics card, so it may use it as a
 console. Other domains don't have ttyN consoles, so attempts to run a
 'mingetty' against them will fail, generating periodic warning
 messages from 'init' about services respawning too fast. They should
-work for domain0 just fine.
-
-In future, we may make the current 'xencons' accept input as well as
-output, so that a getty can be run against it. In the meantime, other
-domains don't have a console suitable for logging in on, so you'll
-have to run sshd and ssh in to them.
-
-To prevent the warning messages you'll need to remove them from
-/etc/inittab for domains>0.  Due to a bug in the RH9 /etc/rc.sysinit
-script #'ing the lines out of /etc/inittab won't work as it ignores
-the '#' and tries to access them anyway.
-
-Also, because domains>0 don't have any privileged access at all,
+work for domain0 just fine.  
+IMPORTANT: To prevent warning messages when running RH9 you'll need to
+remove ttyN from /etc/inittab for domains>0.  Due to a bug in the RH9
+/etc/rc.sysinit script #'ing the lines out of /etc/inittab won't work
+as it ignores the '#' and tries to access them anyway.
+
+Every Xenolinux instance owns a bidirectional 'virtual
+console'. Boot-time output can be directed to this console by
+specifying 'console=xencons0' as a boot parameter. It is also possible
+to log in via the virtual console. To do this, you must run a mingetty
+on the virtual console, which you can achieve as follows:
+ # mkdir -p /dev/xen
+ # mknod /dev/xen/cons c 4 123
+ # echo "c:2345:respawn:/sbin/mingetty --noclear xen/cons" >>/etc/inittab
+If you wish to permit root logins via the virtual console then you must
+also add 'xen/cons' to the list of trusted ttys in /etc/securetty.
+
+Note that, because domains>0 don't have any privileged access at all,
 certain commands in the default boot sequence will fail e.g. attempts
 to update the hwclock, change the console font, update the keytable
 map, start apmd (power management), or gpm (mouse cursor).  Either
index 69e064899080271fce234a9b8da43e07e449843f..b3ed0217bf42a55780bf1ca48604639620973441 100644 (file)
@@ -272,6 +272,16 @@ session. An alternative is to specify '-c' to xc_dom_create.py, or add
 xc_dom_create.py to automatically become teh console terminal after
 starting the domain.
 
+Boot-time output can be directed to this 'virtual console' by
+specifying 'console=xencons0' as a boot parameter. It is also possible
+to log in via the virtual console. To do this, you must run a mingetty
+on the virtual console, which you can achieve as follows:
+ # mkdir -p /dev/xen
+ # mknod /dev/xen/cons c 4 123
+ # echo "c:2345:respawn:/sbin/mingetty --noclear xen/cons" >>/etc/inittab
+If you wish to permit root logins via the virtual console then you must
+also add 'xen/cons' to the list of trusted ttys in /etc/securetty.
+
 
 Manage Running Domains
 ==============================
index 84109dda96e4155033f9e4f9282c34b666a4235d..b826c89dee7571a1cc6570d2a43001593af3ac6d 100644 (file)
@@ -38,7 +38,13 @@ def __send_to_sock(sock):
         data = os.read(0,1)
         if ord(data[0]) == ord(']')-64:
             break
-        sock.send(data)
+        try:
+            sock.send(data)
+        except socket.error, error:
+            if error[0] == errno.EPIPE:
+                sys.exit(0)
+            if error[0] != errno.EINTR:
+                raise
     sys.exit(0)
 
 def connect(host,port):
@@ -69,6 +75,7 @@ def connect(host,port):
             print
             print "************ REMOTE CONSOLE EXITED *****************"
     else:
+        signal.signal(signal.SIGPIPE, signal.SIG_IGN)
         __send_to_sock(sock)
 
 if __name__ == '__main__':
index 4d42d8d9da91f23feeba32166e73a357ed31f7d7..bd9a54698058d0015b36e07bbc746c744f3afbd3 100644 (file)
@@ -151,7 +151,6 @@ static struct tty_struct *xeno_console_table[1];
 static struct termios *xeno_console_termios[1];
 static struct termios *xeno_console_termios_locked[1];
 static struct tty_struct *xeno_console_tty;
-static int xeno_console_use_count;
 
 #define WBUF_SIZE     1024
 #define WBUF_MASK(_i) ((_i)&(WBUF_SIZE-1))
@@ -164,7 +163,7 @@ static void __do_console_io(void)
     control_msg_t   *msg;
     evtchn_op_t      evtchn_op;
     CONTROL_RING_IDX c;
-    int              i, len, work_done = 0;
+    int              i, l, work_done = 0;
     static char      rbuf[16];
 
     if ( xeno_console_tty == NULL )
@@ -174,20 +173,24 @@ static void __do_console_io(void)
     if ( start_info.flags & SIF_INITDOMAIN )
     {
         /* Receive work. */
-        while ( (len = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0 )
-            for ( i = 0; i < len; i++ )
+        while ( (l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0 )
+            for ( i = 0; i < l; i++ )
                 tty_insert_flip_char(xeno_console_tty, rbuf[i], 0);
         if ( xeno_console_tty->flip.count != 0 )
             tty_flip_buffer_push(xeno_console_tty);
 
         /* Transmit work. */
-        if ( wc != wp )
+        while ( wc != wp )
         {
-            len = wp - wc;
-            if ( len > (WBUF_SIZE - WBUF_MASK(wc)) )
-                len = WBUF_SIZE - WBUF_MASK(wc);
-            priv_conwrite(&wbuf[WBUF_MASK(wc)], len);
-            wc += len;
+            l = wp - wc;
+            if ( l > (WBUF_SIZE - WBUF_MASK(wc)) )
+                l = WBUF_SIZE - WBUF_MASK(wc);
+            priv_conwrite(&wbuf[WBUF_MASK(wc)], l);
+            wc += l;
+            wake_up_interruptible(&xeno_console_tty->write_wait);
+            if ( (xeno_console_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+                 (xeno_console_tty->ldisc.write_wakeup != NULL) )
+                (xeno_console_tty->ldisc.write_wakeup)(xeno_console_tty);
         }
 
         return;
@@ -228,32 +231,33 @@ static void __do_console_io(void)
         msg->type    = CMSG_CONSOLE;
         msg->subtype = CMSG_CONSOLE_DATA;
         msg->id      = 0xaa;
-        len = 0;
+        l = 0;
         if ( x_char != 0 ) /* Handle XON/XOFF urgently. */
         {
-            msg->msg[len++] = x_char;
+            msg->msg[l++] = x_char;
             x_char = 0;
         }
-        while ( (len < sizeof(msg->msg)) && (wc != wp) )
-            msg->msg[len++] = wbuf[WBUF_MASK(wc++)];
-        msg->length = len;
+        while ( (l < sizeof(msg->msg)) && (wc != wp) )
+            msg->msg[l++] = wbuf[WBUF_MASK(wc++)];
+        msg->length = l;
     }
     if ( ctrl_if->tx_req_prod != c )
     {
         ctrl_if->tx_req_prod = c;
         work_done = 1;
+        /* There might be something for waiters to do. */
+        wake_up_interruptible(&xeno_console_tty->write_wait);
+        if ( (xeno_console_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+             (xeno_console_tty->ldisc.write_wakeup != NULL) )
+            (xeno_console_tty->ldisc.write_wakeup)(xeno_console_tty);
     }
-        
+
     if ( work_done )
     {
         /* Send a notification to the controller. */
         evtchn_op.cmd = EVTCHNOP_send;
         evtchn_op.u.send.local_port = 0;
         (void)HYPERVISOR_event_channel_op(&evtchn_op);
-
-        /* There might be something for waiters to do. */
-        if ( xeno_console_tty != NULL )
-            wake_up_interruptible(&xeno_console_tty->write_wait);
     }
 }
 
@@ -374,35 +378,64 @@ static void xeno_console_flush_chars(struct tty_struct *tty)
     spin_unlock_irqrestore(&xeno_console_lock, flags);    
 }
 
+static void xeno_console_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+    unsigned long orig_jiffies = jiffies;
+
+    while ( tty->driver.chars_in_buffer(tty) )
+    {
+        set_current_state(TASK_INTERRUPTIBLE);
+        schedule_timeout(1);
+        if ( signal_pending(current) )
+            break;
+        if ( (timeout != 0) && time_after(jiffies, orig_jiffies + timeout) )
+            break;
+    }
+    
+    set_current_state(TASK_RUNNING);
+}
+
 static int xeno_console_open(struct tty_struct *tty, struct file *filp)
 {
     int line;
+    unsigned long flags;
 
     MOD_INC_USE_COUNT;
     line = MINOR(tty->device) - tty->driver.minor_start;
-    if ( line )
+    if ( line != 0 )
     {
         MOD_DEC_USE_COUNT;
         return -ENODEV;
     }
 
+    spin_lock_irqsave(&xeno_console_lock, flags);
     tty->driver_data = NULL;
     if ( xeno_console_tty == NULL )
-    {
         xeno_console_tty = tty;
-        wc = wp = 0;
-        __do_console_io();
-    }
-
-    xeno_console_use_count++;
+    __do_console_io();
+    spin_unlock_irqrestore(&xeno_console_lock, flags);    
 
     return 0;
 }
 
 static void xeno_console_close(struct tty_struct *tty, struct file *filp)
 {
-    if ( --xeno_console_use_count == 0 )
+    unsigned long flags;
+
+    if ( tty->count == 1 )
+    {
+        tty->closing = 1;
+        tty_wait_until_sent(tty, 0);
+        if ( tty->driver.flush_buffer != NULL )
+            tty->driver.flush_buffer(tty);
+        if ( tty->ldisc.flush_buffer != NULL )
+            tty->ldisc.flush_buffer(tty);
+        tty->closing = 0;
+        spin_lock_irqsave(&xeno_console_lock, flags);
         xeno_console_tty = NULL;
+        spin_unlock_irqrestore(&xeno_console_lock, flags);    
+    }
+
     MOD_DEC_USE_COUNT;
 }
 
@@ -417,7 +450,8 @@ int __init xeno_con_init(void)
     xeno_console_driver.type            = TTY_DRIVER_TYPE_SERIAL;
     xeno_console_driver.subtype         = SERIAL_TYPE_NORMAL;
     xeno_console_driver.init_termios    = tty_std_termios;
-    xeno_console_driver.flags           = TTY_DRIVER_REAL_RAW;
+    xeno_console_driver.flags           = 
+        TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_NO_DEVFS;
     xeno_console_driver.refcount        = &xeno_console_refcount;
     xeno_console_driver.table           = xeno_console_table;
     xeno_console_driver.termios         = xeno_console_termios;
@@ -434,6 +468,7 @@ int __init xeno_con_init(void)
     xeno_console_driver.flush_buffer    = xeno_console_flush_buffer;
     xeno_console_driver.throttle        = xeno_console_throttle;
     xeno_console_driver.unthrottle      = xeno_console_unthrottle;
+    xeno_console_driver.wait_until_sent = xeno_console_wait_until_sent;
 
     if ( tty_register_driver(&xeno_console_driver) )
         panic("Couldn't register Xeno console driver\n");